import java.util.*;
import java.awt.Point;

/**
A set of cards.
*/
public class CardSet extends HashSet<Card> {
	
	private HashMap<Integer,Card> idToCard = new HashMap<Integer,Card>();
	
	public CardSet(Collection<Card> initial) {
		super();
		addAll(initial);
	}
	public CardSet(Card initial) {
		super();
		add(initial);
	}
	public CardSet() {
		super();
	}
	
	public boolean add(Card c) {
		idToCard.put(c.getID(),c);	// map id to card, for quick lookup
		return super.add(c);
	}
	
	public void clear() {
		idToCard = new HashMap<Integer,Card>();
		super.clear();
	}
	
	public boolean remove(Card c) {
		idToCard.remove(c.getID());
		return super.remove(c);
	}
	
	/**
	returns the card with the given id.  if there is no such card, returns null.
	*/
	public Card getCardFromID(int id) {
		return idToCard.get(id);
	}
	
	/**
	only here for backwards compatibility.  should be removed later.
	*/
	public List<Card> getDeck() {
		return new ArrayList<Card>(this);
	}
	
	/**
	Returns a copy this set of cards, that is sorted by Z coordinate.  This is provided for convenience, since often you will want iterate through cards from bottom to top, such as when rendering, or finding the top card.
	
	The SortedSet returned is only guaranteed to be in correct order at the time it was created.  If the underlying cards are changed, the SortedSet will probably no longer be in the correct order.  So the set returned by this method should be used immediately, and the method should be called again each subsequent time the SortedSet is needed, rather that saving and keeping the set.
	*/
	public SortedSet<Card> getZSortedSet() {
		TreeSet<Card> sortedset = new TreeSet<Card>(new ZComparator());
		sortedset.addAll(this);
		return sortedset;
	}
	
	public void shuffle() {
		Set<Card> shuffledSet = new HashSet<Card>();
		
		ArrayList<Integer> zedvalues = new ArrayList<Integer>();
		ArrayList<Point> points = new ArrayList<Point>();
		int numCardsInGroup = 0;
		
		for(Card c: this) {
			zedvalues.add(c.getZ());
			points.add(c.getLocation());
			numCardsInGroup++;
			shuffledSet.add(c);			
		}
		
		int[] newOrder = randomPermute(numCardsInGroup);
		
		int index = 0;
		
		for(Card c2: shuffledSet) {
			c2.setLocation(points.get(newOrder[index]));
			c2.setZ(zedvalues.get(newOrder[index]));
			index++;
		}
	}
	
	private int[] randomPermute(int max) {
		ArrayList<Integer> unused = new ArrayList<Integer>();
		for (int i = 0; i < max; i++) {
			unused.add(i);
		}
		
		Random r = new Random();
		int[] order = new int[max];
		for (int i = 0; i < max; i++) {
			int chosen = r.nextInt(unused.size());
			order[i] = unused.get(chosen);
			unused.remove(chosen);
		}
		
		return order;
	}
	
	
	
// 	public Card remove(int cardID) {
// 		return null;
// 	}
// 	
// 	public Card[] remove(int[] cardIDs) {
// 		return null;
// 	}
	
	
	
}

